﻿using ZeroSum.Domain.Repositories;
using ZeroSum.Exceptions;
using ZeroSum.Plugin.Authorization.Datas.Aggregates.RoleAggregate;

namespace ZeroSum.Plugin.Authorization.Datas.Services.Roles;

public class RoleBaseDomainService<TRole> : IRoleBaseDomainService<TRole> where TRole : RoleBase
{
    protected readonly IRepository<TRole, long> RoleRepository;

    public RoleBaseDomainService(IRepository<TRole, long> roleRepository)
    {
        RoleRepository = roleRepository;
    }

    public virtual async Task<TRole> AddAsync(TRole entity, CancellationToken cancellationToken = default)
    {
        await CheckRoleAdd(entity.Name, entity.Code);
        entity.NormalizeCode = entity.Code?.ToUpper();
        return await RoleRepository.AddAsync(entity);
    }

    public virtual async Task CheckRoleUpdate(string? name, string? code, long id)
    {
        var isRoleExist = await RoleRepository.AnyAsync(u => u.Id == id);
        if (!isRoleExist)
            throw AlreadyExistedException.Of($"角色编号为“{id}”的角色不存在！")!;
        var isExist =
            await RoleRepository.AnyAsync(u => (u.Name == name || u.NormalizeCode == code!.ToUpper()) && u.Id != id);
        if (isExist)
            throw AlreadyExistedException.Of($"角色名为“{name}”或者角色编码为“{code}”的角色已存在！")!;
    }

    public virtual async Task UpdateAsync(TRole entity, CancellationToken cancellationToken = default)
    {
        await RoleRepository.UpdateAsync(entity);
    }

    public virtual async Task DeleteAsync(long id, CancellationToken cancellationToken = default)
    {
        await CheckRoleExist(id);
        var entity = await RoleRepository.GetAsync(id);
        await RoleRepository.AddAsync(entity);
    }

    public virtual async Task<TRole> GetByIdAsync(long id, CancellationToken cancellationToken = default)
    {
        await CheckRoleExist(id);
        return await RoleRepository.GetAsync(id);
    }

    private async Task CheckRoleExist(long id)
    {
        var isExist = await RoleRepository.AnyAsync(u => u.Id == id);
        if (!isExist)
            throw AlreadyExistedException.Of($"角色编号为“{id}”的角色不存在！")!;
    }

    private async Task CheckRoleAdd(string? name, string? code)
    {
        var isExist =
            await RoleRepository.AnyAsync(u => code != null && (u.Name == name || u.NormalizeCode == code.ToUpper()));
        if (isExist)
            throw AlreadyExistedException.Of($"角色名为“{name}”或者角色编码为“{code}”的角色已存在！")!;
    }
}